package demo.java.lang.instrument;

import java.lang.instrument.Instrumentation;

/**
 * “java.lang.instrument”包的具体实现，依赖于 JVMTI。JVMTI（Java Virtual Machine Tool Interface）是一套由 Java 虚拟机提供的， 为
 * JVM相关的工具提供的本地编程接口集合。JVMTI 提供了一套”代理”程序机制，可以支持第三方工具程序以代理的方式连接和访问 JVM， 并利用 JVMTI 提供的丰富的编程接口，完成很多跟 JVM 相关的功能。
 *
 */
public class InstrumentDemo {

    /**
     * 直接获取对象的大小。这种方法得到的是Shallow Size，即遇到引用时，只计算引用的长度，不计算所引用的对象的实际大小。如果要计算所引用对象的实际大小，可以通过递归的方式去计算。
     * java.lang.instrument.Instrumentation的实例必须通过指定javaagent的方式才能获得，具体的步骤如下：
     * <li>1. 定义一个类，提供一个premain方法: public static void premain(String agentArgs, Instrumentation instP)
     * <li>2. 创建META-INF/MANIFEST.MF文件，内容是指定PreMain的类是哪个： Premain-Class: sizeof.ObjectShallowSize
     * <li>3. 把这个类打成jar，然后用java -javaagent XXXX.jar XXX.main的方式执行
     * 
     */
    public void instrumentation(Instrumentation instrumentation) {
        long size = instrumentation.getObjectSize(new Object());

    }

}

class ObjectShallowSize {
    private static Instrumentation instrumentation;

    public static void premain(String agentArgs, Instrumentation instP) {
        instrumentation = instP;
    }

    public static long sizeOf(Object obj) {
        return instrumentation.getObjectSize(obj);
    }
}